Build Automation with OpenCode Autoheal
This guide explains how to run an automated Docusaurus build check every 4 hours, detect failures, and let OpenCode attempt minimal safe fixes.
Objective
- Run build checks on a schedule.
- Detect build/runtime errors from logs.
- Apply targeted fixes automatically when possible.
- Record what was fixed and what remains unresolved.
Package Location
The automation package is versioned in this repository:
/home/rezriz/github/01-production/docusaurus-build-if-changed/opencode-docusaurus-autoheal
Runtime deployment path currently used by systemd:
/home/rezriz/github/01-production/opencode-docusaurus-autoheal
Core Files
| File | Purpose |
|---|---|
run-autoheal.sh | Executes opencode run in non-interactive mode and writes logs |
prompt.md | AI runbook: run build script, diagnose errors, fix minimally, verify |
install-cron.sh | Optional cron fallback installer |
logs/ | Runtime logs (cron.log, run-*.log, summary.log, incidents.log) |
Required Preconditions
- OpenCode installed and accessible in PATH for the service user.
- Model/provider auth configured.
- Permissions configured for external directories if the site is outside working dir.
- Docker/sudo commands used by the build script can run non-interactively.
systemd Timer (Recommended)
Use user-level service and timer for resilient scheduling.
systemctl --user daemon-reload
systemctl --user enable --now opencode-docusaurus-autoheal.timer
Run once manually:
systemctl --user start opencode-docusaurus-autoheal.service
Verify:
systemctl --user status opencode-docusaurus-autoheal.service --no-pager
systemctl --user list-timers opencode-docusaurus-autoheal.timer --all
journalctl --user -u opencode-docusaurus-autoheal.service -n 100 --no-pager
Non-Interactive Behavior
The runner uses:
opencode run --model openai/gpt-5.3-codex "$(<prompt.md)"
This avoids TUI interaction and is suitable for scheduled jobs.
Logging Model
The runner writes four log streams:
logs/cron.logfor timeline events.logs/run-*.logfor raw run output.logs/summary.log(JSONL) for per-run structured outcomes.logs/incidents.log(JSONL) for runs with detected errors or unresolved items.
Structured fields include:
ai_status,root_cause,actions_takenfiles_changed,resolved,unresolvedverification_result,error_detected,error_count
Prompt Contract
Each run requires AI to report:
- Status:
SUCCESSorFAILED - Root cause
- Actions taken
- Files changed
- Resolved
- Unresolved
- Verification result
This keeps each automation cycle auditable.
Operational Notes
- If no watched files changed, build may be skipped; this is expected behavior.
- Non-blocking warnings can still appear while the build is considered successful.
- Keep fixes minimal and avoid auto-push behavior in autonomous mode.